package com.example.field;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

/**
 * @author zhangs
 * @version v1.0
 * @decription Field测试
 * @date 2021/4/7 17:04
 **/
public class FieldDemo {
    static class Parent {
        public Integer pId;
        public static int pParent;
        private String pHappy;
        private static String pYes;
    }

    static class User extends Parent {
        public String username;
        private Integer age;
        private static int sex;
        private final static String hobby;
        public final String[] addrs;

        static {
            // 静态代码初始化块
            hobby = "篮球";
        }

        {
            // 实例代码初始化块
            addrs = new String[]{"湖南"};
        }

        @Override
        public String toString() {
            return "User{" +
                    "pId=" + pId +
                    ", username='" + username + '\'' +
                    ", age=" + age +
                    ", addrs=" + Arrays.toString(addrs) +
                    ",sex=" + sex +
                    ",hobby=" + hobby +
                    '}';
        }
    }

    private static String format(Field field) {
        return String.format("\t%s %s %s;",
                // 获取属性的访问修饰符
                Modifier.toString(field.getModifiers()),
                // 获取属性的类型
                field.getType().getName(),
                // 获取属性名
                field.getName());
    }

    public static void main(String[] args) {
        Class<User> clazz = User.class;
        // 获取所有的public属性，包括继承
        Field[] fields = clazz.getFields();
        System.out.println("getFields():");
        for (Field field : fields) {
            System.out.println(format(field));
        }

        // 获取所有的方法，不包括继承
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println("getDeclaredMethods():");
        for (Field field : declaredFields) {
            System.out.println(format(field));
        }

        try {
            // 创建实例
            User user = clazz.getDeclaredConstructor().newInstance();
            /* 给username赋值 */
            Field username = clazz.getDeclaredField("username");
            username.set(user, "李四");
            /* 给age赋值 */
            Field age = clazz.getDeclaredField("age");
            age.setAccessible(true);
            age.set(user, 18);
            /* 给静态字段赋值 sex */
            Field sex = clazz.getDeclaredField("sex");
            sex.setAccessible(true);
            sex.set(null, 18);
            /* 给静态常量赋值 hobby */
            // JVM在编译期间，会把final类型的String进行优化，在编译期间
            // 会把String处理成常量，所以无法修改

            /* 给final的数组属性赋值 */
            Field addr = clazz.getDeclaredField("addrs");
            addr.setAccessible(true); //设置访问权限
            addr.set(user, new String[]{"世界", "你好"});

            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
